home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
MCASM.RAR
/
MC_ASM.EXE
/
WROX_ASM
/
CH10
/
PROGRAMS
/
DARHH7.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-05-30
|
10KB
|
613 lines
; Haffman decoding
; Written by Malakhov K.A.
; Compile with TASM 3.0 or latter
; TASM DARHH7.ASM /MX /ZX /O
; CALL: haff_decode(char *buffinput,unsigned int inputlength,
; char *buffoutput,unsigned int outputlength);
model large
PUBLIC _haff_decode
.code
_haff_decode PROC C FAR
ARG buffi:dword,ileng:word,buffo:dword,oleng:word
USES ds,es,di,si,bx,cx,dx
; main
; Allocate memory
mov ah,48h
mov bx,2049
int 21h
jnc @@impl_t000
jmp @@imp_err
@@impl_t000: mov cs:seg1,ax
mov ah,48h
mov bx,2049
int 21h
jnc @@impl_t001
jmp @@imp_err
@@impl_t001: mov cs:seg2,ax
jmp @@main_1
@@main_0: jmp @@imp_err
@@main_1: mov ax,word ptr buffi+2
mov ds,ax
mov si,word ptr buffi
mov ax,ileng
cmp ax,0
ja @@new_010
jmp @@imp_err
@@new_010: mov cs:counti,ax
mov ax,word ptr buffo+2
mov es,ax
mov di,word ptr buffo
mov ax,oleng
mov cs:counto,ax
cmp ax,0
ja @@imp_005
jmp @@imp_err
@@imp_005:
; decompression
call darhhaff
cmp ax,0
jne @@implode_e1
@@implode_e: jmp @@imp_err
@@implode_e1: jmp @@imp_exit
darhhaff proc NEAR
; Read
lodsb
dec word ptr cs:counti
push ax
cmp cs:counti,0
pop ax
jne @@darh_001
jmp @@implode_err
@@darh_001: mov cs:CRCodr,al
lodsb
dec word ptr cs:counti
push ax
cmp cs:counti,0
pop ax
jne @@darh_010
jmp @@implode_err
; Read the length of header
@@darh_010: xor ah,ah
inc ax
mov cs:hafflen,ax
mov dx,ax
push cs
pop es
; Clear tresh
mov cx,256
lea di,chartab
xor ax,ax
rep stosb
mov cx,256
lea di,freqtab
rep stosw
mov cx,1024
lea di,hafftab
rep stosb
mov cx,dx
mov cs:codcnt,0
; Read header chartab
lea di,chartab
@@darh_020: lodsb
dec word ptr cs:counti
push ax
cmp cs:counti,0
pop ax
ja @@darh_030
jmp @@implode_err
@@darh_030: stosb
loop @@darh_020
; Read header freqtab
mov cx,cs:hafflen
lea di,freqtab
@@darh_040: lodsb
dec word ptr cs:counti
push ax
cmp cs:counti,0
pop ax
ja @@darh_050
jmp @@implode_err
@@darh_050: xchg ah,al
lodsb
dec word ptr cs:counti
push ax
cmp cs:counti,0
pop ax
ja @@darh_055
jmp @@implode_err
@@darh_055: xchg ah,al
stosw
loop @@darh_040
@@darh_057:
mov cs:savesi,si
; Build the tree
; Prepare the table of weights
mov cx,256
lea di,codtab
xor al,al
rep stosb
; MIN
@@impl_089: mov bx,65535
xor si,si
mov cx,cs:hafflen
@@impl_090: mov ax,cs:freqtab[si]
cmp ax,0
je @@impl_092
cmp bx,ax
jbe @@impl_092
mov bx,ax
mov cs:minpos1,si
@@impl_092: add si,2
loop @@impl_090
mov cs:exit,1
mov bx,65535
xor si,si
mov cx,cs:hafflen
cmp cx,1
ja @@impl_094
mov ax,cs:minpos1
shr ax,1
mov cl,1
call shift
jmp @@impl_220
@@impl_094: mov ax,cs:freqtab[si]
cmp ax,0
je @@impl_096
cmp bx,ax
jb @@impl_096
cmp si,cs:minpos1
je @@impl_096
mov bx,ax
mov cs:exit,0
mov cs:minpos2,si
@@impl_096: add si,2
loop @@impl_094
mov al,cs:exit
cmp al,0
je @@impl_098
jmp @@impl_220
@@impl_098:
mov ax,cs:minpos1
shr ax,1
mov si,ax
mov ax,cs:minpos2
shr ax,1
mov di,ax
mov al,cs:codtab[si]
mov ah,cs:codtab[di]
cmp al,0
jne @@impl_100
cmp ah,0
je @@impl_099
jmp @@impl_125
; Variant 1
@@impl_099: inc byte ptr cs:codcnt
mov ax,si
mov cl,0
call shift
mov ax,di
mov cl,1
call shift
mov al,cs:codcnt
mov cs:codtab[si],al
mov cs:codtab[di],al
mov si,cs:minpos1
mov di,cs:minpos2
mov ax,cs:freqtab[di]
add cs:freqtab[si],ax
mov cs:freqtab[di],0
jmp @@impl_089
; Variant 2
@@impl_100:
cmp ah,0
je @@impl_102
jmp @@impl_140
@@impl_102:
mov ax,cs:minpos1
shr ax,1
mov si,ax
mov dl,cs:codtab[si]
mov cx,256
xor si,si
@@impl_105: cmp dl,cs:codtab[si]
jne @@impl_110
push cx
mov ax,si
xor cl,cl
call shift
pop cx
@@impl_110: inc si
loop @@impl_105
mov ax,cs:minpos2
shr ax,1
mov cl,1
call shift
mov ax,cs:minpos1
shr ax,1
mov si,ax
mov ax,cs:minpos2
shr ax,1
mov di,ax
mov al,cs:codtab[si]
mov cs:codtab[di],al
mov si,cs:minpos1
mov di,cs:minpos2
mov ax,cs:freqtab[di]
add cs:freqtab[si],ax
mov cs:freqtab[di],0
jmp @@impl_089
@@impl_125:
mov ax,cs:minpos2
shr ax,1
mov si,ax
mov dl,cs:codtab[si]
mov cx,256
xor si,si
@@impl_130: cmp dl,cs:codtab[si]
jne @@impl_135
push cx
mov ax,si
xor cl,cl
call shift
pop cx
@@impl_135: inc si
loop @@impl_130
mov ax,cs:minpos1
shr ax,1
mov cl,1
call shift
mov ax,cs:minpos2
shr ax,1
mov si,ax
mov ax,cs:minpos1
shr ax,1
mov di,ax
mov al,cs:codtab[si]
mov cs:codtab[di],al
mov si,cs:minpos2
mov di,cs:minpos1
mov ax,cs:freqtab[di]
add cs:freqtab[si],ax
mov cs:freqtab[di],0
jmp @@impl_089
; Variant 3
@@impl_140:
mov ax,cs:minpos1
shr ax,1
mov si,ax
mov dl,cs:codtab[si]
mov cx,256
xor si,si
@@impl_145: cmp dl,cs:codtab[si]
jne @@impl_150
push cx
mov ax,si
xor cl,cl
call shift
pop cx
@@impl_150: inc si
loop @@impl_145
mov ax,cs:minpos2
shr ax,1
mov si,ax
mov dl,cs:codtab[si]
mov cx,256
xor si,si
@@impl_155: cmp dl,cs:codtab[si]
jne @@impl_160
push cx
mov ax,si
mov cl,1
call shift
pop cx
@@impl_160: inc si
loop @@impl_155
mov ax,cs:minpos1
shr ax,1
mov si,ax
mov dl,cs:codtab[si]
mov ax,cs:minpos2
shr ax,1
mov si,ax
mov dh,cs:codtab[si]
mov cx,256
xor si,si
@@impl_165: cmp dl,cs:codtab[si]
jne @@impl_170
mov cs:codtab[si],dh
@@impl_170: inc si
loop @@impl_165
mov si,cs:minpos2
mov di,cs:minpos1
mov ax,cs:freqtab[di]
add cs:freqtab[si],ax
mov cs:freqtab[di],0
jmp @@impl_089
; Calculating the number of bytes
@@impl_220: mov di,2
mov cx,256
@@impl_230: mov al,cs:hafftab[di]
xor ah,ah
xor dx,dx
mov bx,8
div bx
mov cs:hafftab[di],8
cmp dx,0
je @@impl_240
mov cs:hafftab[di],dl
inc ax
@@impl_240: mov cs:hafftab[di+1],al
add di,4
loop @@impl_230
; The number of dearchieve bytes
mov cx,256
mov ax,es
mov ds,ax
lea si,freqtab
mov cs:countb,0
@@impl_245: lodsw
add cs:countb,ax
loop @@impl_245
; To fill the table
mov cx,256
mov ax,cs:seg1
mov ds,ax
mov ax,cs:seg2
mov es,ax
xor si,si
@@impl_t010: push cx
; Mask
mov dl,byte ptr cs:hafftab[si+3]
cmp dl,0
je @@impl_t040
mov ax,0ffffh
mov cl,3
shl dl,cl
mov cl,24
sub cl,dl
sub cl,byte ptr cs:hafftab[si+2]
shl ax,cl
mov cs:svsi,ax
; Word
mov dh,byte ptr cs:hafftab[si]
mov dl,byte ptr cs:hafftab[si+1]
mov cs:svdi,dx
@@impl_t020: mov ax,cs:svsi
and ax,dx
cmp ax,cs:svdi
jne @@impl_t040
mov bx,dx
; Direction betwin memory blocks
cmp bx,32768
ja @@impl_t030
mov ax,si
shr ax,1
shr ax,1
mov byte ptr ds:[bx],al
inc dx
jmp short @@impl_t020
@@impl_t030: sub bx,32768
mov ax,si
shr ax,1
shr ax,1
mov byte ptr es:[bx],al
inc dx
jmp short @@impl_t020
@@impl_t040: add si,4
pop cx
loop @@impl_t010
; Decoder
mov cs:shiftb,0
mov ax,oleng
mov cs:counto,ax
mov ax,word ptr buffi+2
mov ds,ax
mov si,cs:savesi
mov ax,word ptr buffo+2
mov es,ax
mov di,word ptr buffo
mov cs:CRCod,0
; Load the word
@@impl_250: mov ah,ds:[si]
mov al,ds:[si+1]
mov dh,al
mov dl,ds:[si+2]
; Shift
@@impl_254: mov cl,cs:shiftb
shl ax,cl
shl dx,cl
mov al,dh
mov bx,ax
cmp bx,32768
ja @@impl_p010
mov cx,cs:seg1
jmp short @@impl_p020
@@impl_p010: sub bx,32768
mov cx,cs:seg2
@@impl_p020: push ds
mov ds,cx
mov al,byte ptr ds:[bx]
pop ds
mov cs:svsi,si
xor ah,ah
mov si,ax
; Output from loop (found)
@@impl_315:
stosb
add cs:CRCod,al
dec word ptr cs:counto
mov ax,cs:counto
cmp ax,0
ja @@impl_312
jmp @@implode_err
@@impl_312: dec word ptr cs:countb
mov bx,si
mov si,cs:svsi
mov cl,2
shl bx,cl
add bx,3
mov al,cs:hafftab[bx]
dec al
xor ah,ah
add si,ax
sub word ptr cs:counti,ax
mov al,cs:hafftab[bx-1]
mov ah,cs:shiftb
add ah,al
mov cx,cs:countb
cmp cx,0
je @@impl_318
cmp ah,8
jb @@impl_314
sub ah,8
inc si
dec word ptr cs:counti
@@impl_314: mov cs:shiftb,ah
jmp @@impl_250
; Output
@@impl_318:
@@impl_320: mov ax,oleng
sub ax,cs:counto
cmp ax,0
ja @@impl_330
inc ax
@@impl_330:
@@implode_err: mov ax,0
jmp short @@impl_exit
@@implode_noerr:
; Check CRC
mov bl,cs:CRCodr
cmp bl,cs:CRCod
je @@impl_exit
mov ax,0
@@impl_exit: ret
darhhaff endp
; Procedure for set a mask
maska proc NEAR
push bx
push cx
push dx
mov bx,si
mov cl,2
shl bx,cl
add bx,3
cmp dl,cs:hafftab[bx]
jne @@maska_010
dec bx
mov cl,8
sub cl,cs:hafftab[bx]
mov dl,0ffh
shl dl,cl
and ah,dl
@@maska_010: pop dx
pop cx
pop bx
ret
maska endp
; Shift procedure
shift proc NEAR
push bx
push di
push dx
rcr cl,1
pushf
mov bx,ax
mov al,cs:chartab[bx]
xor ah,ah
mov cl,2
shl ax,cl
mov di,ax
xor bx,bx
mov dx,bx
add dx,1
@@shift_010: cmp bx,dx
ja @@shift_020
mov al,cs:hafftab[di+bx]
popf
rcr al,1
pushf
mov cs:hafftab[di+bx],al
inc bx
jmp short @@shift_010
@@shift_015: mov cs:errflag,1
jmp short @@shift_030
@@shift_020: popf
mov cl,byte ptr cs:hafftab[di+bx]
cmp cl,16
ja @@shift_015
@@shift_030: inc byte ptr cs:hafftab[di+bx]
pop dx
pop di
pop bx
ret
shift endp
; Data
counti dw ? ; Input bytes
counto dw ? ; Output bytes
countb dw ? ; Counter of bytes
savesi dw ?
hafflen dw ?
errflag db ?
shiftb db ?
currhaff dw ?
minpos1 dw ?
minpos2 dw ?
codcnt db ?
exit db ?
kajuk dw ?
ident db 'MSI'
CRCod db ?
CRCodr db ?
flag dw ?
svsi dw ?
svdi dw ?
seg1 dw ? ; Address of heshing table
seg2 dw ? ;
chartab db 256 dup(?)
freqtab dw 256 dup(?)
codtab db 256 dup(?)
hafftab db 1024 dup(?)
@@imp_err: mov ax,0
jmp short @@imp_exit
@@imp_noerr:
@@imp_exit: push ax
mov ax,cs:seg1
mov es,ax
mov ah,49h
int 21h
mov ax,cs:seg2
mov es,ax
mov ah,49h
int 21h
pop ax
ret
_haff_decode ENDP
END